<template>
    <el-form-item prop="sqlInfos" class="block-item" style="width: 100%;">
        <el-card class="form-card" style="width: 100%;">
            <template #header>
                <div class="card-header">
                    <span>报表对应SQL</span>
                    <div class="header-actions">
                        <el-button type="primary" size="small" :disabled="!props.hasTable"
                            @click="handleRuleGenerateSQL">规则生成</el-button>
                        <el-button type="primary" size="small" :disabled="!props.hasTable"
                            @click="handleAIGenerateSQL">AI生成</el-button>
                        <el-button type="primary" size="small" :disabled="!props.hasTable"
                            @click="handleValidateSQL">SQL验证</el-button>
                    </div>
                </div>
            </template>
            <el-mention v-model="props.form.sqlInfos" type="textarea" 
                :prefix="[' ', '.']"
                :options="options" 
                style="width: 100%"
                autosize
                @search="handleSearch"
                placeholder="Please input sql" />
        </el-card>
    </el-form-item>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import type { MentionOption } from 'element-plus'

const props = defineProps({
    form: {
        type: Object,
        required: true
    },
    hasTable: {
        type: Boolean,
        required: true
    },
    columnList: {
        type: Object,
        default: () => ({})
    }
})

// 通过props.form.tableInfos获取所有的库名，去重
const dbList = ref<string[]>([...new Set(props.form.tableInfos.map((item: { source: string }) => item.source as string))])
const dbTables = computed(() => {
    return props.form.tableInfos.reduce((acc: { [x: string]: any[] }, table: { source: string | number; table: any }) => {
        if (!acc[table.source]) {
            acc[table.source] = []
        }
        acc[table.source].push(table.table)
        return acc
    }, {})
})

// 定义一个字符串对应列表的内容，key包括db名称，table名称和table别名
// value包括{db名称: [表名(表描述)], table名称: [字段名(字段描述)], table别名: [字段名(字段描述)]}
const statementContext = ref<string, Array>({})
// 通过props.form.tableInfos中的内容，填充到statementContext中
props.form.tableInfos.forEach((item: { source: string; table: any}) => {
    if (!statementContext.value[item.source]) {
        statementContext.value[item.source] = []
    }
    statementContext.value[item.source].push(item.table)
    if (!statementContext.value[item.table]) {
        statementContext.value[item.table] = props.columnList[item.table]
    }
})

const MOCK_DATA: Record<string, string[]> = {
  ' ': ['Fuphoenixes', 'kooriookami', 'Jeremy', 'btea'],
  '.': ['1.0', '2.0', '3.0'],
}
const value = ref('')
const options = ref<MentionOption[]>([])

const handleSearch = (_: string, prefix: string) => {
  // 当触发空格且前面有FROM时显示数据库列表
  if (prefix === ' ') {
    console.log('dbList', dbList.value)
    const inputBefore = props.form.sqlInfos.slice(0, -1).trim() // 获取空格前的输入内容
    const lastFromIndex = inputBefore.lastIndexOf('from')
    
    // 检查是否包含完整的FROM关键字（前后有空格或位于开头）
    if (lastFromIndex >= 0 && 
        (lastFromIndex === 0 || /\s/.test(inputBefore[lastFromIndex - 1])) &&
        (lastFromIndex + 4 === inputBefore.length || /\s/.test(inputBefore[lastFromIndex + 4]))) {
      options.value = dbList.value.map(value => ({ value }));
      return;
    }
  }else if (prefix === '.') {
    const inputBefore = props.form.sqlInfos.slice(0, -1); // 获取点号前的输入内容
    const context = parseContext(inputBefore);

    switch (context.type) {
      case 'database':
        // 显示该数据库下的表格列表
        options.value = (dbTables.value[context.database] || [])
          .map(table => ({ value: table }));
        break;

      case 'table':
      case 'field':
        // 获取表格字段列表
        const columns = props.columnList[context.table] || [];
        options.value = columns
          .map(col => ({ value: col.columnName }));
        break;

      case 'alias':
        // 通过别名映射获取实际表结构
        const actualTable = aliasMap.value[context.alias];
        options.value = (props.columnList[actualTable] || [])
          .map(col => ({ value: col.columnName }));
        break;

      default:
        options.value = MOCK_DATA[prefix] || [];
    }
    return;
  }
  
  // 保留原有的mock数据处理
  options.value = (MOCK_DATA[prefix] || []).map((value) => ({
    value,
  }))
}

const emit = defineEmits(['rule-generate', 'ai-generate', 'validate-sql', 'sql-input', 'select'])

const handleRuleGenerateSQL = () => {
    emit('rule-generate')
}

const handleAIGenerateSQL = () => {
    emit('ai-generate')
}

// 转换数据结构
const databases = computed(() => {
    const result = {}
    // props.dbList.forEach(db => {
    //     result[db] = {
    //         tables: (props.tableList[db] || []).reduce((acc, table) => {
    //             acc[table.tableName] = {
    //                 fields: (props.columnList[table.tableName] || []).map(col => ({
    //                     name: col.columnName,
    //                     type: col.columnType,
    //                     description: col.columnDesc
    //                 }))
    //             }
    //             return acc
    //         }, {})
    //     }
    // })
    // return result
})

const aliasMap = ref<Record<string, string>>({})
const currentInput = ref('')

// 处理输入事件
const handleSqlInput = (value: string) => {
    currentInput.value = value
    emit('sql-input', value)
}

// 解析当前输入上下文
// 修改后的parseContext函数
const findAlias = (input: string) => {
    // 按分号分割语句，取最后一条有效语句
    const statements = input.split(';').filter(s => s.trim());
    const lastStatement = statements[statements.length - 1] || '';

    // 匹配子查询别名及字段
    const subqueryPattern = /\b(SELECT\b.*?\bFROM\b[\s\S]*?)\s+AS\s+(\w+)\s*(?:\(([^)]+)\))?/gi;

    // 提取当前语句中的所有表别名
    const aliasPattern = /(?:FROM|JOIN)\s+([\w.]+)(?:\s+(?:AS\s+)?(\w+))?/gi;
    const matches = lastStatement.matchAll(aliasPattern);

    aliasMap.value = {}

    // 处理子查询映射
    let subMatch;
    while ((subMatch = subqueryPattern.exec(input)) !== null) {
        const [_, subquery, alias, columns] = subMatch;
        if (alias) {
            // 解析子查询字段
            const fieldMap = {};
            if (columns) {
                columns.split(',').forEach(col => {
                    const [orig, renamed] = col.split(/s+ASs+/i);
                    fieldMap[renamed?.trim() || orig.trim()] = orig.trim();
                });
            } else {
                // 解析SELECT字段
                const fieldPattern = /SELECT\s+(.+?)\s+FROM/gi.exec(subquery);
                if (fieldPattern) {
                    fieldPattern[1].split(',').forEach(field => {
                        const [orig, renamed] = field.split(/s+ASs+/i);
                        const key = renamed?.trim() || orig.trim();
                        fieldMap[key] = orig.trim().replace(/.*?\./,'');
                    });
                }
            }
            aliasMap.value[alias] = fieldMap;
        }
    }
    
    for (const match of matches) {
        const [_, table, alias] = match;
        if (alias) {
            aliasMap.value[alias] = table.split('.').pop()!; // 提取纯表名
        } else if (table) {
            const tableName = table.split('.').pop()!;
            aliasMap.value[tableName] = tableName;
        }
    }
}

const parseContext = (input: string) => {
    findAlias(input)
    // 提取.前面的一个单词
    const prefixMatch = input.match(/(\w+)\s*\.$/);
    const prefix = prefixMatch ? prefixMatch[1] : null;

    // 判断prefix是否在aliasMap中
    if (prefix && aliasMap.value[prefix]) {
        return {
            type: 'alias',
            alias: prefix,
            context: aliasMap.value[prefix]
        }
    }
}

// 获取建议列表
// 修改后的querySearch过滤逻辑
const querySearch = async (queryString: string, cb: any) => {
    const context = parseContext(currentInput.value)
    let suggestions = []

    // switch (context.type) {
    //     case 'database':
    //         suggestions = props.dbList.map(db => ({
    //             name: db,
    //             type: '数据库',
    //             description: ''
    //         }))
    //         break

    //     case 'table':
    //         const tables = props.tableList[context.database] || []
    //         suggestions = tables.map(table => ({
    //             name: `${context.database}.${table.tableName}`,
    //             type: '表',
    //             description: table.tableDesc
    //         }))
    //         break

    //     case 'field':
    //         if (context.database && context.table) {
    //             const columns = props.columnList[context.table] || []
    //             suggestions = columns.map(col => ({
    //                 name: `${context.database}.${context.table}.${col.columnName}`,
    //                 type: col.columnType,
    //                 description: col.columnDesc
    //             }))
    //         } else if (context.context) {
    //             suggestions = context.context.fields.map(field => ({
    //                 name: field.name,
    //                 type: field.type,
    //                 description: field.description
    //             }))
    //         }
    //         break
    // }

    // 过滤匹配项
    // 修正后的过滤逻辑
    const searchText = context.prefix ?
        queryString.replace(context.prefix, '').toLowerCase() :
        queryString.toLowerCase()

    // const filtered = suggestions.filter(item =>
    //     item.name.toLowerCase().startsWith(context.prefix + searchText)
    // )

    // cb(filtered)
}

const handleValidateSQL = () => {
    emit('validate-sql')
}
</script>

<style scoped>
.header-actions {
    display: flex;
    gap: 8px;
}

.suggestion-item {
    padding: 4px 8px;
}

.suggestion-item small {
    color: #999;
    font-size: 12px;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.sql-autocomplete .suggestion-item {
    padding: 8px;
    line-height: 1.5;
}

.sql-autocomplete .main-info {
    display: flex;
    justify-content: space-between;
    margin-bottom: 4px;
}

.sql-autocomplete .type {
    color: #666;
    font-size: 0.8em;
}

.sql-autocomplete .description {
    color: #999;
    display: block;
    font-size: 0.8em;
}

.el-popper.sql-autocomplete {
    max-width: 600px;
}
</style>